package testBase;


import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import java.util.Properties;

import java.util.Set;
import java.util.concurrent.TimeUnit;


import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.StringDescription;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeClass;

import pages.AnyPage;
import pages.HomePage;
import pages.InternalPage;
import pages.LoginPage;
import pages.MoviePage;
import pages.MyProfilePage;
import pages.Page;
import pages.UserManagmentPage;
import pages.UserPage;

import com.opera.core.systems.OperaDriver;

import fw.ApplicationManager;

public class TestBase {
	
	protected static ApplicationManager app;
	
	protected static WebDriver driver;
	protected WebDriverWait wait;
	protected StringBuffer verificationErrors = new StringBuffer();
	InputStream stream = null;
	InputStreamReader reader = null;
	protected Properties props = new Properties();
	private String configFile;
	
	
	@AfterSuite
	public void tearDown() throws Exception {
		stop();
	}
	
	@BeforeClass
	protected void getSeleniumDriver() {
		app = ApplicationManager.getInstance();
		
		if (configFile == null) {
			configFile = "appProperties";
		}
		InputStream stream;
		try {
			stream = new FileInputStream(new File(configFile));
			reader = new InputStreamReader(stream,"UTF-8");
			props.load(reader);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		String browser = props.getProperty("browser", "firefox");
		
		if (driver == null) {
			driver = getDriver(browser);
			driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
		}
	}	

	protected WebDriver getDriver(String browser) {

		if ("firefox".equals(browser)) {
			driver = new FirefoxDriver();
			wait = new WebDriverWait(driver, 10);
		} else if ("ie".equals(browser)) {
			driver = new InternetExplorerDriver();
			wait = new WebDriverWait(driver, 10);
		} else if ("chrome".equals(browser)) {
			driver = new ChromeDriver();
			wait = new WebDriverWait(driver, 10);
		} else if ("opera".equals(browser)) {
			driver = new OperaDriver();
			wait = new WebDriverWait(driver, 10);
		}
		return driver;
		
	}
	
	protected WebDriver stop() {
		driver.quit();
		return driver;
		
	}
	
	public <T> void assertThat(T actual, Matcher<T> matcher) {
		assertThat("", actual, matcher);
	}
	
	public <T> void assertThat(String reason, T actual, Matcher<T> matcher) {
		if (!matcher.matches(actual)) {
			Description description = new StringDescription();
			description.appendText(reason)
				.appendText("\nExpected: ")
				.appendDescriptionOf(matcher)
				.appendText("\n     got: ")
				.appendValue(actual)
				.appendText("\n");
	        
			throw new java.lang.AssertionError(description.toString());
		}
	}
	
	protected void openUrl(String url) {
		driver.get(url);
	}
	
	protected Object getSetElement(Set<?> objects, int toGet) {
		return objects.toArray()[toGet];
	}

	public void openBaseUrl() {
		driver.get("http://localhost/php4dvd/");
		initializationPageObgect();
	}

	private void initializationPageObgect() {
		PageFactory.initElements(driver, AnyPage.class);
		PageFactory.initElements(driver, HomePage.class);
		PageFactory.initElements(driver, InternalPage.class);
		PageFactory.initElements(driver, LoginPage.class);
		PageFactory.initElements(driver, MoviePage.class);
		PageFactory.initElements(driver, MyProfilePage.class);
		PageFactory.initElements(driver, Page.class);
		PageFactory.initElements(driver, UserManagmentPage.class);
		PageFactory.initElements(driver, UserPage.class);		
	}

	public void logInByAdmin() {
		openBaseUrl();
		Page.login();
		String language = props.getProperty("language", "english");
		selectLanguage(language);
	}

	private void selectLanguage(String language) {
		WebElement div = driver.findElement(By.className("languages"));
		WebElement languages = div.findElement(By.tagName("ul"));
		if ("english".equals(language)) {
			languages.findElement(By.cssSelector("a[href='./?lang=en_US']")).click();
		} 
		if ("nederlands".equals(language)) {
			languages.findElement(By.cssSelector("a[href='./?lang=nl_NL']")).click();
		}
		
	}
	
	public void logOut() {
		Page.logout();
		wait.until(alertIsPresent()).accept();
	}
	
}
